package il.ac.braude.sona.control;

import il.ac.braude.sona.constants.ButtonPermission;
import il.ac.braude.sona.constants.Mssg;
import il.ac.braude.sona.constants.P;
import il.ac.braude.sona.constants.Resources;
import il.ac.braude.sona.entities.ChangeRequest;
import il.ac.braude.sona.entities.LoginKit;
import il.ac.braude.sona.entities.Messege;
import il.ac.braude.sona.entities.User;
import il.ac.braude.sona.entities.Worker;
import il.ac.braude.sona.gui.list_table.ListTable;
import il.ac.braude.sona.gui.list_table.ListTableFrame;
import il.ac.braude.sona.gui.list_table.ListTableModel;
import il.ac.braude.sona.gui.menu.MenuFrame;
import il.ac.braude.sona.gui.mytables.ChangeRequestTableFrame;
import il.ac.braude.sona.gui.mytables.ChangeRequestTableModel;
import il.ac.braude.sona.gui.mytables.MessegeTableFrame;
import il.ac.braude.sona.ocsf.client.Client;
import il.ac.braude.sona.ocsf.client.ServerResponseListener;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JOptionPane;

/**
 * The MainController conatins methods to view main menu form, buttons permissions in menu,
 * messages to user, pending requests and worker list   
 * @author Ofek Ron
 * @author Avihay Avitan
 * @author Nitzan Inbar
 * @author Sasha Rozenthal
 */

public class MainController implements ActionListener {

	private CreateChangeRequestController createControl = new CreateChangeRequestController();
	private ViewRequestController viewControl = new ViewRequestController();
	private ReportsController reportControl = new ReportsController();
	private ExtensionsController extController = new ExtensionsController();
	private SupervisorActionController supAct = new SupervisorActionController();
	private ManagementAndReistrationControll manageControl=new ManagementAndReistrationControll();
	private MenuFrame menuFrame = new MenuFrame();
	private JButton mssgsButton;
	private User mUser;
	private int counter;
	private ArrayList<Worker> worker ;
/**
 * 
 * This method executes the actions done on main menu.
 * @param userLoginKit the permissions and session variables for current user session.
 */
	public void execMainMenuForm(LoginKit userLoginKit) {
		mUser = userLoginKit.getUser();
		menuFrame.setTitle(Resources.Strings.ICMsystem + " - " + mUser.getFullName());
		handlePendingRequests(userLoginKit);
		handleMssgs(userLoginKit);
		menuFrame.addButton(Resources.Strings.CreateChangeReq,this);
		menuFrame.addButton(Resources.Strings.ViewRequestByID,this);
		if (mUser.hasPremission(ButtonPermission.view_reports))
			menuFrame.addButton(Resources.Strings.Reports, this);
		if (mUser.hasPremission(ButtonPermission.view_all_requests))
			menuFrame.addButton(Resources.Strings.ViewAllRequests, this);
		if (mUser.hasPremission(ButtonPermission.ViewExtension))
		    menuFrame.addButton(ButtonPermission.ViewExtension,this);
		if (mUser.hasPremission(ButtonPermission.View_supervisor_actions))
		    menuFrame.addButton(ButtonPermission.View_supervisor_actions,this);
		if (mUser.hasPremission(ButtonPermission.ManagementRegistration))
		    menuFrame.addButton(ButtonPermission.ManagementRegistration,this);
		if (mUser.hasPremission(ButtonPermission.viewWorkers))
		    menuFrame.addButton(Resources.Strings.ViewWorkers,this);
		menuFrame.showFrame();
	}
	
	/**
	 * This method is in charge of messages to the the logged in user.
	 * @param userLoginKit the permissions and session variables for current user session.
	 */
	private void handleMssgs(LoginKit userLoginKit) {
		menuFrame.addButton(Resources.Strings.Messeges,new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					Client.getInstance().sendToServer(new ServerResponseListener() {

						@SuppressWarnings("unchecked")
						@Override
						public void onServerResponse(Mssg mssg) {
							if (mssg.is(P.error)) {
								JOptionPane.showMessageDialog(null,
										(mssg.getMessege()));
								return;
							}
							if (!((ArrayList<Messege>)mssg.getMessege()).isEmpty()){	
							MessegeTableFrame tableFrame = new MessegeTableFrame(Resources.Strings.Messeges,(ArrayList<Messege>) mssg.getMessege());
							tableFrame.showFrame();
							}
							else JOptionPane.showMessageDialog(null,"No messages for you...");
						}
					}, new P.ViewMssg(P.ViewMssg.view_all_mssgs,mUser.getID()));

				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
	}
	/**
	 * This method is in charge of "translating" the user click to program action. 
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		if (((JButton)e.getSource()).getText().equals(Resources.Strings.CreateChangeReq))
			createControl.execCreateChangeRequest();
		if (((JButton)e.getSource()).getText().equals(Resources.Strings.ViewRequestByID))
			viewControl.execViewChangeRequest();
		if (((JButton)e.getSource()).getText().equals(Resources.Strings.ViewAllRequests))
			viewControl.execViewAllChangeRequests();
		if (((JButton)e.getSource()).getText().equals(Resources.Strings.Reports))
			reportControl.selectReport();
		if (((JButton)e.getSource()).getText().equals(Resources.Strings.ViewWorkers))
			execViewWorkers();
		if (((JButton)e.getSource()).getText().equals(ButtonPermission.ViewExtension))
			extController.execViewExtensionlist();
		if (((JButton)e.getSource()).getText().equals(ButtonPermission.View_supervisor_actions)){
			supAct.execViewSupervisorActions();
			}
		if (((JButton)e.getSource()).getText().equals(ButtonPermission.ManagementRegistration)){
			manageControl.execManagementRegistration();
		}
	}
/**
 * This method is in charge of showing the workers list to display.
 */
	public void execViewWorkers() {
		Mssg mssg = new Mssg("workers list");
		final ListTableFrame tableFrame = new ListTableFrame("Workers List");
		try
		{
			Client.getInstance().sendToServer(new ServerResponseListener() {
				@SuppressWarnings("unchecked")
				@Override
				public void onServerResponse(Mssg mssg) {
					if (mssg.is(P.error)) {
					JOptionPane.showMessageDialog(null,
							mssg.getMessege());
						return;
					}
					if ((worker = new ArrayList<Worker>((ArrayList<Worker>)mssg.getMessege()))!=null)
					{
						tableFrame.getContentPane().removeAll();
						ListTableModel<Worker> model =new ListTableModel<Worker>(worker);
						tableFrame.setTable(new ListTable<Worker>(model));
					//	tableFrame.setPreferredSize(new Dimension(720,600));
						tableFrame.setResizable(false);
						tableFrame.showFrame();
				}
			}
			}
			, mssg);

		} catch (Exception e) {

			JOptionPane.showMessageDialog(menuFrame,
					String.format("Report Error"));
		}

		}
	/**
	 * This method is in charge of executing the pending requests unequally for each user 
	 * @param userLoginKit the permissions and session variables for current user session.
	 */
	private void handlePendingRequests(LoginKit userLoginKit) {
		mssgsButton = new JButton(Resources.Strings.PendingRequests);
		mssgsButton.setText(Resources.Strings.PendingRequests);
		menuFrame.addButton(mssgsButton,new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					Client.getInstance().sendToServer(new ServerResponseListener() {

						@Override
						public void onServerResponse(Mssg mssg) {
							if (mssg.is(P.error)) {
								JOptionPane.showMessageDialog(null,
										(mssg.getMessege()));
								return;
							}
							if (!((ArrayList<ChangeRequest>)mssg.getMessege()).isEmpty()){	
							ChangeRequestTableFrame tableFrame = new ChangeRequestTableFrame();
							tableFrame.setTitle(Resources.Strings.PendingRequests);
							tableFrame.setTable(new ChangeRequestTableModel((ArrayList<ChangeRequest>) mssg.getMessege()));
							tableFrame.showFrame();
							}
							else JOptionPane.showMessageDialog(null,"No pending requests for you...");

						}
					}, new P.ViewMssg(P.ViewMssg.view_all_pending,mUser.getID()));

				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		Client.getInstance().registerMssgListenerByType(P.server_mssg, new ServerResponseListener() {
			@Override
			public void onServerResponse(Mssg mssg) {
				counter++;
				mssgsButton.setText(Resources.Strings.PendingRequests);
				JOptionPane.showMessageDialog(menuFrame, Resources.Strings.NewPendingRequest);
			}
		});
	}
	
	/**
	 * This method is in charge of deleting messages to users if needed.
	 * @param msg message to delete.
	 * @return Runnable
	 */
	
	public static Runnable deleteMssg(final Messege msg){
		return (new Runnable ()
	      {
	     	@Override
			public void run(){
	    		try {
	    			Mssg mssg = new Mssg(Resources.Strings.DeleteMssg, msg);
	    			Client.getInstance().sendToServer(new ServerResponseListener() {

	    				@SuppressWarnings("unchecked")
	    				@Override
	    				public void onServerResponse(Mssg mssg) {
	    					if (mssg.is(P.error)) {
	    						JOptionPane.showMessageDialog(null,mssg.getMessege());
	    						return;
	    					}
	    				}
	    			}, mssg);

	    		} catch (Exception e) {
	    			JOptionPane.showMessageDialog(null, Resources.Strings.ConnectFailed);
	    		}
	     	}
	      });
	}
}
